package com.huaguoguo.spring.beans.factory;

import com.huaguoguo.spring.execption.BeansException;
import com.huaguoguo.spring.execption.NoSuchBeanDefinitionException;
import com.sun.istack.internal.Nullable;

/**
 * bean工厂总接口
 * @author huaguoguo
 */
public interface BeanFactory {

    /**
     * 工厂bean的标识
     */
    String FACTORY_BEAN_PREFIX = "&";

    /**
     * 根据beanName获取容器中的bean
     * @param name
     * @return
     * @throws BeansException
     */
    Object getBean(String name) throws BeansException;

    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    /**
     * @param name the name of the bean to retrieve
     * @param args arguments to use when creating a bean instance using explicit arguments
     * (only applied when creating a new instance as opposed to retrieving an existing one)
     * @return an instance of the bean
     * @throws BeansException if the bean could not be created
     */
    Object getBean(String name, Object... args) throws BeansException;

    /**
     * 根据bean类型获取bean，如果有多个默认取bean类名首字母小写的bean
     * 例如： 有多个User类型的bean，默认取bean的name为user的bean
     * @param requiredType
     * @param <T>
     * @return
     * @throws BeansException
     */
    <T> T getBean(Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

    boolean containsBean(String name);

    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

    @Nullable
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;


    String[] getAliases(String name);

}
